package com.msx.openapi.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.msx.constants.IsDeleteEnum;
import com.msx.exception.BizException;
import com.msx.pojo.*;
import com.msx.user.service.*;
import com.msx.util.RedissonManager;
import com.msx.util.ResponseResult;
import com.msx.util.StatusCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.Date;

/**
 * 安全认证swagger
 * 安全认证模块
 */
@RestController
@RequestMapping("/certificate")
@Api(tags = "秒速侠接口文档(用户安全认证接口)")
@Log4j2
@CrossOrigin
public class SecurityCertificateController {

    @Autowired
    private RedisTemplate redisTemplate;
    //身份认证
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private UserIdentityHomeInterface userIdentityHomeInterface;

    //淘宝认证
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private IdentityTaoBaoServiceInterface identityTaoBaoServiceInterface;

    //运营商认证
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private OperatorServiceInterface tOperatorServiceInterface;

    //联系人
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private LinkManServiceInterface linkManServiceInterface;

    //绑卡验证
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private TiedcardServiceInterface tiedcardServiceInterface;

    //通讯录验证
    @Reference(timeout = 6000,retries=0,version = "2.0.0")
    private AddressbookServiceInterface addressbookServiceInterface;

    //redis锁
    @Autowired
    private static Redisson redisson = RedissonManager.getRedisson();

    @Autowired
    private HttpServletRequest HttpServletRequest;

    @PostMapping("/identity/orc")
    @ApiOperation(value = "orc验证",notes = "orc验证",produces = "application/json")
    public ResponseResult identityorc(String frontImage){
        String tou = HttpServletRequest.getHeader("tou");
        log.info("请求头："+tou);
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        if (StringUtils.isBlank(frontImage))
        return new ResponseResult().error(StatusCode.ERROR,"图片为空");
        try {
            String s = Base64.getEncoder().encodeToString(frontImage.getBytes());
            return userIdentityHomeInterface.identityOrc(s);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseResult().error(StatusCode.ERROR,"认证有误,请重新上传");
        }
    }

    /**
     * 银行卡认证
     * @param name
     * @param code
     * @param frontImage
     * @param backImage
     * @param liveImage
     * @return
     */
    @PostMapping("/identity")
    @ApiOperation(value = "身份证验证",notes = "身份证验证",produces = "application/x-www-form-urlencoded")
    public ResponseResult identity(String name, String code,
                                   String frontImage, String backImage, String liveImage){
        /**
         *   @RequestParam("frontImage") MultipartFile frontImage,
         *   @RequestParam("backImage") MultipartFile backImage,
         *   @RequestParam("liveImage") MultipartFile liveImage
         */
        String tou = HttpServletRequest.getHeader("tou");
        log.info("请求头："+tou);
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);


        if (StringUtils.isBlank(name)){
            throw new BizException(StatusCode.ERROR,"姓名为空");
        }
        if (StringUtils.isBlank(code)){
            throw new BizException(StatusCode.ERROR,"身份证号为空");
        }
        if (StringUtils.isBlank(frontImage.toString())){
            throw new BizException(StatusCode.ERROR,"身份证正面为空");
        }
        if (StringUtils.isBlank(backImage.toString())){
            throw new BizException(StatusCode.ERROR,"身份证号反面为空");
        }
        if (StringUtils.isBlank(liveImage.toString())){
            throw new BizException(StatusCode.ERROR,"活体照片为空");
        }
        log.info("身份证："+code);
        //获取锁
        RLock redissonLock = redisson.getLock(name);
        boolean lock = redissonLock.tryLock();
        log.info("当前redission锁的状态:"+lock);
        if (!lock){
            return new ResponseResult().error(StatusCode.ERROR,"正在认证中，请稍后");
        }
        try {
            String baseFrontImage = Base64.getEncoder().encodeToString(frontImage.getBytes());
            String backImageImage = Base64.getEncoder().encodeToString(backImage.getBytes());
            String liveImageImage = Base64.getEncoder().encodeToString(liveImage.getBytes());
            return userIdentityHomeInterface.UserIdentityHome(falg,name,code,baseFrontImage,backImageImage,liveImageImage);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(StatusCode.ERROR,"转换异常");
        }finally {
            //判断有没有获取到锁
            if (redissonLock.isLocked()){
                //很明显，就是得到当前线程是否获取锁
                if (redissonLock.isHeldByCurrentThread()){
                    //释放锁
                    redissonLock.unlock();
                }
            }
        }
    }

    /**
     * 淘宝认证
     * @param taobao
     * @return
     */
    @PostMapping("/identity/taobao")
    @ApiOperation(value = "淘宝验证",notes = "淘宝验证",produces = "application/json")
    public ResponseResult identitytaobao(@RequestBody Taobao taobao, HttpServletRequest request){

        String tou = request.getHeader("tou");
        log.info("请求头："+tou);

        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        taobao.setUserId(Integer.valueOf(falg));
        if (StringUtils.isBlank(taobao.getTaobaoUser())){
            throw new BizException(StatusCode.ERROR,"淘宝账户不能为空");
        }
        if (StringUtils.isBlank(taobao.getTaobaoPwd())){
            throw new BizException(StatusCode.ERROR,"淘宝密码不能为空");
        }
        if (StringUtils.isBlank(taobao.getUserId().toString())){
            throw new BizException(StatusCode.ERROR,"用户Id不能为空");
        }

        //获取锁
        RLock redissonLock = redisson.getLock(taobao.getTaobaoUser());
        boolean lock = redissonLock.tryLock();
        log.info("当前redission锁的状态:"+lock);
        if (!lock){
            return new ResponseResult().error(StatusCode.ERROR,"正在认证中，请稍后");
        }
        try {
            return identityTaoBaoServiceInterface.IdentityTaoBaoService(taobao);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(StatusCode.ERROR,"请重试");
        }finally {
            //判断有没有获取到锁
            if (redissonLock.isLocked()){
                //很明显，就是得到当前线程是否获取锁
                if (redissonLock.isHeldByCurrentThread()){
                    //释放锁
                    redissonLock.unlock();
                }
            }
        }

    }

    /**
     * 联系人认证
     * @param linkman
     * @return
     */
    @PostMapping("/identity/linkMan")
    @ApiOperation(value = "联系人验证",notes = "联系人验证",produces = "application/json")
    public ResponseResult identityoperator(@RequestBody Linkman linkman){

        if (StringUtils.isBlank(linkman.getUrgencyName())){
            throw new BizException(StatusCode.ERROR,"紧急联系人不能为空");
        }
        if (StringUtils.isBlank(linkman.getUrgencyMobile())){
            throw new BizException(StatusCode.ERROR,"紧急联系人手机号不能为空");
        }
        if (StringUtils.isBlank(linkman.getUrgencyRelation())){
            throw new BizException(StatusCode.ERROR,"紧急联系人关系不能为空");
        }
        if (StringUtils.isBlank(linkman.getFirstName())){
            throw new BizException(StatusCode.ERROR,"第一联系人姓名不能为空");
        }
        if (StringUtils.isBlank(linkman.getFirstMobile())){
            throw new BizException(StatusCode.ERROR,"第一联系人手机号不能为空");
        }
        if (StringUtils.isBlank(linkman.getFirstRelation())){
            throw new BizException(StatusCode.ERROR,"第一联系人关系不能为空");
        }
        if (StringUtils.isBlank(linkman.getSecondName())){
            throw new BizException(StatusCode.ERROR,"第二联系人姓名不能为空");
        }
        if (StringUtils.isBlank(linkman.getSecondMobile())){
            throw new BizException(StatusCode.ERROR,"第二联系人手机号不能为空");
        }
        if (StringUtils.isBlank(linkman.getSecondRelation())){
            throw new BizException(StatusCode.ERROR,"第二联系人关系不能为空");
        }

        String tou = HttpServletRequest.getHeader("tou");

        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }


        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        linkman.setUserId(Integer.valueOf(falg));

        //获取锁
        RLock redissonLock = redisson.getLock(linkman.getFirstMobile());
        boolean lock = redissonLock.tryLock();
        log.info("当前redission锁的状态:"+lock);
        if (!lock){
            return new ResponseResult().error(StatusCode.ERROR,"正在认证中，请稍后");
        }
        try {
              return linkManServiceInterface.identificationTbLinkMan(linkman);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(StatusCode.ERROR,"请重试");
        }finally {
            //判断有没有获取到锁
            if (redissonLock.isLocked()){
                //很明显，就是得到当前线程是否获取锁
                if (redissonLock.isHeldByCurrentThread()){
                    //释放锁
                    redissonLock.unlock();
                }
            }
        }
    }

    /**
     * 运营商发送验证码
     * @param phone
     * @return
     */
    @PostMapping("/identity/operator/sms")
    @ApiOperation(value = "运营商发送验证码",notes = "运营商发送验证码",produces = "application/json")
    public ResponseResult identityoperatorsms(@RequestHeader(value = "tou") String tou, String phone){
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }

        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        Sms sms =new Sms();
        if (StringUtils.isBlank(phone)){
            throw new BizException(StatusCode.ERROR,"手机号不能为空");
        }
        sms.setMobile(phone);
        sms.setSendTime(new Date());
        sms.setContent("验证码");
        sms.setUserId(Integer.valueOf(falg));
        sms.setIsDelete(String.valueOf(IsDeleteEnum.OK.getCode()));
        sms.setSmsType("运营商认证");
        return tOperatorServiceInterface.OutSms(sms);
    }
    /**
     * 运营商认证
     * @param phone
     * @param code
     * @return
     */
    @PostMapping("/identity/operator")
    @ApiOperation(value = "运营商验证",notes = "运营商验证",produces = "application/json")
    public ResponseResult identityoperator(@RequestHeader(value = "tou") String tou,
                                           String phone,
                                           String code){
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }

        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);


        Operator operator = new Operator();
        if (StringUtils.isBlank(phone)){
            throw new BizException(StatusCode.ERROR,"手机号不能为空");
        }
        if (StringUtils.isBlank(code)){
            throw new BizException(StatusCode.ERROR,"验证码不能为空");
        }
        operator.setMobile(phone);
        operator.setCode(code);
        operator.setUserId(Integer.valueOf(falg));
        return tOperatorServiceInterface.IdentityOperator(operator);
    }


    /**
     * 绑卡获取验证码
     * @param phone
     * @param bankId
     * @param name
     * @param bankcode
     * @param indentcode
     * @return
     */
    @PostMapping("/identity/tiedcard/sms")
    @ApiOperation(value = "绑卡获取验证",notes = "绑卡获取验证",produces = "application/json")
    public ResponseResult identitytiedcardsms(String phone,
                                              String bankId,
                                              String name,
                                              String bankcode,
                                              String indentcode){
        if (StringUtils.isBlank(phone)){
            throw new BizException(StatusCode.ERROR,"手机号不能为空");
        }
        if (StringUtils.isBlank(bankId)){
            throw new BizException(StatusCode.ERROR,"银行卡ID不能为空");
        }
        if (StringUtils.isBlank(name)){
            throw new BizException(StatusCode.ERROR,"姓名不能为空");
        }
        if (StringUtils.isBlank(bankcode)){
            throw new BizException(StatusCode.ERROR,"银行卡号不能为空");
        }
        if (StringUtils.isBlank(indentcode)){
            throw new BizException(StatusCode.ERROR,"身份证号不能为空");
        }
        String tou = HttpServletRequest.getHeader("tou");
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        Tiedcard tiedcard = new Tiedcard();
        tiedcard.setBankId(Integer.valueOf(bankId));
        tiedcard.setName(name);
        tiedcard.setIdentityCode(indentcode);
        tiedcard.setBankCode(bankcode);
        tiedcard.setUserId(Integer.valueOf(falg));
        tiedcard.setReservedMobile(phone);
        log.info("绑卡信息:"+tiedcard);
        return tiedcardServiceInterface.TiedcardOut(tiedcard);
    }


    /**
     *  绑卡
     * @param code
     * @param phone
     * @param bankId
     * @param name
     * @param bankcode
     * @param indentcode
     * @return
     */
    @PostMapping("/identity/tiedcard")
    @ApiOperation(value = "绑卡验证",notes = "绑卡验证",produces = "application/json")
    public ResponseResult identitytiedcard(
                                            String code,
                                            String phone,
                                           String bankId,
                                           String name,
                                           String bankcode,
                                           String indentcode){
        if (StringUtils.isBlank(code)){
            throw new BizException(StatusCode.ERROR,"验证码不能为空");
        }
        if (StringUtils.isBlank(phone)){
            throw new BizException(StatusCode.ERROR,"手机号不能为空");
        }
        if (StringUtils.isBlank(bankId)){
            throw new BizException(StatusCode.ERROR,"银行卡ID不能为空");
        }
        if (StringUtils.isBlank(name)){
            throw new BizException(StatusCode.ERROR,"姓名不能为空");
        }
        if (StringUtils.isBlank(bankcode)){
            throw new BizException(StatusCode.ERROR,"银行卡号不能为空");
        }
        if (StringUtils.isBlank(indentcode)){
            throw new BizException(StatusCode.ERROR,"身份证号不能为空");
        }
        String tou = HttpServletRequest.getHeader("tou");
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        Tiedcard tiedcard = new Tiedcard();
        tiedcard.setBankId(Integer.valueOf(bankId));
        tiedcard.setName(name);
        tiedcard.setIdentityCode(indentcode);
        tiedcard.setBankCode(bankcode);
        tiedcard.setUserId(Integer.valueOf(falg));
        tiedcard.setReservedMobile(phone);
        tiedcard.setCode(code);
        log.info("绑卡信息:"+tiedcard);
        return tiedcardServiceInterface.indeupdate(tiedcard);
    }

    /**
     * 绑卡获取信息
     * @param
     * @return
     */
    @PostMapping("/identity/tiedcard/id")
    @ApiOperation(value = "绑卡获取信息",notes = "绑卡获取信息",produces = "application/json")
    public ResponseResult identitytiedcards(){
        String tou = HttpServletRequest.getHeader("tou");
        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        log.info("请求头："+tou);
        String falg =  redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            return new ResponseResult().error(StatusCode.ERROR,"请从新登录");
        }
        log.info("用户信息："+falg);
        return tiedcardServiceInterface.findById(falg);
    }


    /**
     * 通信录获取信息认证
     * @return
     */
    @PostMapping("/identity/addressbook/id")
    @ApiOperation(value = "通信录获取信息",notes = "通信录获取信息",produces = "application/json")
    public ResponseResult addressbook(@RequestHeader(value = "tou") String tou){

        if (StringUtils.isBlank(tou)){
            return new ResponseResult().error(400,"请重新登录!");
        }
        log.info("请求头："+tou);

        String falg = redisTemplate.opsForValue().get(tou).toString();

        if (StringUtils.isBlank(falg)){
            throw new BizException(StatusCode.ERROR,"ID不能为空");
        }
        return addressbookServiceInterface.update(falg);
    }

}
